<template>
  <div class="limit-page">
    <transition name="el-zoom-in-top">
      <el-form v-show="searchFormVisible" inline size="mini" :model="searchForm" ref="searchMenuForm" @keyup.enter.native="searchLimitConfigHandle">
        <el-form-item prop="word" label="限流配置检索">
          <el-input v-model="searchForm.word" clearable placeholder="请输入检索的接口路径"></el-input>
        </el-form-item>
        <el-form-item prop="type">
          <el-select v-model="searchForm.type" clearable placeholder="请选择限流类型">
            <el-option v-for="typeEnum in typeEnumList" :key="'type' + typeEnum.value"
                       :label="typeEnum.name" :value="typeEnum.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="status">
          <el-select v-model="searchForm.status" placeholder="请选择状态">
            <el-option v-for="statusEnum in statusEnumList" :key="'status' + statusEnum.value"
                       :label="statusEnum.name" :value="statusEnum.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button :disabled="dataLoad" @click="searchLimitConfigHandle" type="primary"
                     icon="el-icon-search">查询</el-button>
          <el-button :disabled="dataLoad" @click="resetSearchFormHandle" plain
                     icon="el-icon-refresh-right">重置</el-button>
        </el-form-item>
      </el-form>
    </transition>
    <div class="l-tool">
      <el-button :disabled="dataLoad" @click="openLimitConfigDialogHandle(undefined)"
                 type="primary" size="mini" plain icon="el-icon-plus">添加</el-button>
      <el-button :disabled="limitConfigSelection.length === 0 || dataLoad || buttonLoad" @click="batchUpdateStatusHandle(1)"
                 type="success" size="mini" plain icon="el-icon-circle-plus-outline">批量启用</el-button>
      <el-button :disabled="limitConfigSelection.length === 0 || dataLoad || buttonLoad" @click="batchUpdateStatusHandle(0)"
                 type="warning" size="mini" plain icon="el-icon-circle-close">批量禁用</el-button>
      <el-button :disabled="limitConfigSelection.length === 0 || dataLoad || buttonLoad" @click="batchDeleteLimitConfigHandle"
                 type="danger" size="mini" plain icon="el-icon-delete">批量删除</el-button>
      <log-stats-popover ref="logStatsPopoverRef" @add-limit-config="$refs.limitConfigDialog.saveInit($event)"></log-stats-popover>

      <right-tool-bar :search-visible="searchFormVisible" :search-load="dataLoad"
                      @toggle-search="searchFormVisible = !searchFormVisible" @refresh-table="getPageLimitConfigList" />
    </div>
    <el-table
      v-loading="dataLoad"
      element-loading-text="限流配置列表加载中..."
      element-loading-spinner="el-icon-loading"
      :data="limitConfigList"
      @selection-change="(val) => this.limitConfigSelection = val"
      ref="limitConfigTable"
    >
      <el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
      <el-table-column fixed prop="requestKey" header-align="center" align="center" label="接口路径" width="150"></el-table-column>
      <el-table-column prop="type" header-align="center" align="center" label="限流类型">
        <template v-slot="{row}">
          {{ row.type | baseFormat(typeEnumList) }}
        </template>
      </el-table-column>
      <el-table-column prop="timeNum" header-align="center" align="center" label="时间数值"></el-table-column>
      <el-table-column prop="timeType" header-align="center" align="center" label="单位" >
        <template v-slot="{row}">
          {{ row.timeType | baseFormat(timeTypeEnumList) }}
        </template>
      </el-table-column>
      <el-table-column prop="maxNum" header-align="center" align="center" label="最大次数" ></el-table-column>
      <el-table-column prop="limitTime" header-align="center" align="center" label="限流时长（秒）" width="120"></el-table-column>
      <el-table-column prop="version" header-align="center" align="center" label="版本号"></el-table-column>
      <el-table-column prop="status" header-align="center" align="center" label="状态" width="65">
        <template v-slot="{row}">
          {{ row.status | baseFormat(statusEnumList) }}
        </template>
      </el-table-column>
      <el-table-column prop="updateTime" header-align="center" align="center" label="更新时间" width="135"></el-table-column>
      <el-table-column prop="updateUser" header-align="center" align="center" label="更新用户"></el-table-column>
      <el-table-column prop="createTime" header-align="center" align="center" label="创建时间" width="135"></el-table-column>
      <el-table-column prop="createUser" header-align="center" align="center" label="创建用户"></el-table-column>
      <el-table-column
        fixed="right"
        header-align="left"
        width="170"
        label="操作">
        <template v-slot="{ row }">
          <div>
            <el-button type="text" icon="el-icon-view" @click="$refs.viewDialog.initDialog(row)">
              查看
            </el-button>
            <el-button type="text" icon="el-icon-edit" @click="openLimitConfigDialogHandle(row)">
              修改
            </el-button>
          </div>
          <div>
            <el-button v-if="row.status === 1" type="text" icon="el-icon-check" @click="useLimitConfigHandle(row)">
              启用
            </el-button>
            <el-button v-if="row.status === 0" type="text" icon="el-icon-close" @click="disableLimitConfigHandle(row)">
              禁用
            </el-button>
            <el-button type="text" icon="el-icon-view" @click="$refs.historyDialog.initDialog(row.id, row.requestKey, row.type)">
              历史版本
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      @size-change="sizeChangeHandle"
      @current-change="currentChangeHandle"
      :disabled="dataLoad"
      :current-page="searchForm.page"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="searchForm.limit"
      :total="totalNum"
      layout="total, sizes, prev, pager, next, jumper"
      class="paging">
    </el-pagination>

    <!-- 新增/修改限流配置弹出框 -->
    <limit-config-dialog :type-enum-list="typeEnumList" :time-type-enum-list="timeTypeEnumList"
                         :status-enum-list="statusEnumList" @close-dialog="closeLimitConfigDialogHandle"
                         ref="limitConfigDialog" />
    <!-- 查看限流配置弹出框 -->
    <view-dialog :type-enum-list="typeEnumList" :time-type-enum-list="timeTypeEnumList"
                 :status-enum-list="statusEnumList" :use-status="useStatus" ref="viewDialog" />

    <!-- 历史限流配置查看弹出框 -->
    <history-dialog :type-enum-list="typeEnumList" :time-type-enum-list="timeTypeEnumList"
                    :status-enum-list="statusEnumList" ref="historyDialog" />
  </div>
</template>

<script>
  import RightToolBar from "@/components/common/right-toolbar";
  import LimitConfigDialog from "@/components/limit/save-update";
  import ViewDialog from "@/components/limit/view";
  import HistoryDialog from "@/components/limit/history";
  import LogStatsPopover from "@/components/limit/log-stats";

  export default {
    layout: 'admin',
    name: "admin-limit-manage",
    components: { RightToolBar, LimitConfigDialog, ViewDialog, HistoryDialog, LogStatsPopover },
    data() {
      return {
        // 限流配置数据列表
        limitConfigList: [],
        // 限流配置列表选中数据
        limitConfigSelection: [],
        // 限流类型枚举列表
        typeEnumList: [],
        // 时间枚举列表
        timeTypeEnumList: [],
        // 状态枚举列表
        statusEnumList: [],
        // 状态为’可用‘的枚举值
        useStatus: undefined,
        // 限流配置检索表单显示状态[true-显示 false-隐藏]
        searchFormVisible: true,
        // 限流配置检索表单对象
        searchForm: {
          // 接口路径
          word: '',
          // 限流类型[0-请求 1-异常]
          type: '',
          // 状态
          status: 0,
          // 当前展示页码
          page: 1,
          // 当前页显示个数
          limit: 10,
        },
        // 限流配置总数
        totalNum: 0,
        // 数据加载状态[false-不加载 true-加载]
        dataLoad: false,
        // 按钮禁用状态[true-禁用 false-可用]
        buttonLoad: false,
      }
    },
    filters: {
      /**
       * 枚举映射方法
       * @param {number} value 参数值
       * @param {Array} list  枚举列表
       */
      baseFormat(value, list) {
        for (let obj of list) {
          if (obj.value === value) {
            return obj.name;
          }
        }
        return '未知';
      }
    },
    created() {
      if (process.client) {
        this.getEnumList();
        this.getPageLimitConfigList();
      }
    },
    /**
     * 路由切换回调函数
     * @param to   目标路由对象
     * @param from 来源路由对象（本页面的路由对象）
     * @param next 执行函数
     */
    beforeRouteLeave(to, from, next) {
      // 清理定时器
      this.$refs.logStatsPopoverRef.statsOnOffHandle(false);
      // 路由跳转
      next();
    },
    methods: {
      /**
       * 检索限流配置事件
       */
      searchLimitConfigHandle() {
        this.searchForm.page = 1;

        this.getPageLimitConfigList();
      },
      /**
       * 重置检索表单对象事件
       */
      resetSearchFormHandle() {
        // 重置限流配置检索表单对象
        this.$refs.searchMenuForm.resetFields();
        // 重置页码
        this.searchForm.page = 1
      },
      /**
       * 分页获取限流配置方法
       */
      getPageLimitConfigList() {
        // 开始数据加载
        this.dataLoad = true;
        this.$axios.$post('/sys/limit-config/page/list', this.searchForm)
          .then(({ data }) => {
            this.limitConfigList = data.data;
            this.totalNum = data.totalNum;
          })
          .catch(() => {})
          .finally(() => {
            // 数据加载结束
            this.dataLoad = false;
          })
      },
      /**
       * 获取限流配置枚举数据方法
       */
      getEnumList() {
        this.$axios.$get("/sys/limit-config/enums")
          .then(({ data }) => {
            this.typeEnumList = data.typeEnumList;
            this.timeTypeEnumList = data.timeTypeEnumList;
            this.statusEnumList = data.statusEnumList;
            this.useStatus = data.useStatus;
          })
          .catch(() => {})
      },
      /**
       * 每页显示个数变化事件
        * @param {number} size 最新显示个数值
       */
      sizeChangeHandle(size) {
        let searchForm = this.searchForm;
        searchForm.page = 1;
        searchForm.limit = size;
        this.getPageLimitConfigList()
      },
      /**
       * '点击特定页码'、'上一页'、'下一页'操作事件
       * @param {number} index 最新页码
       */
      currentChangeHandle(index) {
        let searchForm = this.searchForm;
        if (searchForm.page === index) {
          return
        }
        searchForm.page = index
        this.getPageLimitConfigList()
      },
      /**
       * 打开限流配置弹出框事件
       * @param {Object} limitConfig 限流配置对象
       */
      openLimitConfigDialogHandle(limitConfig) {
        this.$refs.limitConfigDialog.initDialog(limitConfig);
      },
      /**
       * 关闭限流配置弹出框事件
       * @param {boolean} refresh 是否刷新表格数据[true-刷新 false-不刷新]
       */
      closeLimitConfigDialogHandle(refresh) {
        if (refresh) {
          this.getPageLimitConfigList();
        }
      },
      /**
       * 批量更新限流配置数据状态事件
       * @param {number} oldStatus 旧状态
       */
      batchUpdateStatusHandle(oldStatus) {
        // 按钮禁用
        this.buttonLoad = true;
        let limitConfigList = this.limitConfigSelection;
        // 过滤出所有符合状态的限流配置数据主键
        limitConfigList = limitConfigList.filter(limitConfig => limitConfig.status === oldStatus).map(limitConfig => {
          return {
            id: limitConfig.id,
            requestKey: limitConfig.requestKey,
            type: limitConfig.type
          }
        });
        if (limitConfigList.length === 0) {
          this.notify('', '操作提示', `选中数据中不含有${oldStatus === 0 ? '' : '不'}可用限流配置数据，无需进行${oldStatus === 0 ? '停用' : '启用'}操作`);
          // 按钮恢复可用
          this.buttonLoad = false;
          return;
        }
        this.$confirm(`您确定要批量${oldStatus === 0 ? '停用' : '启用'}限流配置操作吗？`, '批量操作提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            let url = "/sys/limit-config/batch/" + (oldStatus === 0 ? 'disable' : 'use');
            return this.$axios.$post(url, limitConfigList);
          })
          .then(() => {
            this.notify('success', '操作成功', `批量${oldStatus === 0 ? '停用' : '启用'}限流配置操作成功`);

            // 刷新列表
            this.getPageLimitConfigList();
          })
          .catch(() => {})
          .finally(() => {
            // 按钮恢复可用
            this.buttonLoad = false;
          })
      },
      /**
       * 启用限流配置事件
       * @param {Object} limitConfig 限流配置对象
       */
      useLimitConfigHandle(limitConfig) {
        // 按钮禁用
        this.buttonLoad = true;
        this.$axios.$post('/sys/limit-config/check', limitConfig)
          .then(({ data }) => {
            let message = '您确定要启用限流配置吗?'
            if (data.checkFlag) {
              // 校验拒绝
              message = '已存在可用的限流配置数据，是否要新增限流配置，停用旧的限流配置?'
            }
            return this.$confirm(message, '操作提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            });
          })
          .then(() => {
            let data = {
              id: limitConfig.id,
              requestKey: limitConfig.requestKey,
              type: limitConfig.type
            }
            return this.$axios.$post('/sys/limit-config/use', data);
          })
          .then(() => {
            this.notify('success', '操作成功', '启用限流配置操作成功');

            // 刷新列表
            this.getPageLimitConfigList();
          })
          .catch(() => {})
          .finally(() => {
            // 按钮恢复可用
            this.buttonLoad = false;
          })
      },
      /**
       * 禁用限流配置事件
       * @param {Object} limitConfig 限流配置对象
       */
      disableLimitConfigHandle(limitConfig) {
        this.$confirm('您确定要禁用限流配置吗？', '操作提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            let data = {
              id: limitConfig.id,
              requestKey: limitConfig.requestKey,
              type: limitConfig.type
            }
            return this.$axios.$post('/sys/limit-config/disable', data);
          })
          .then(() => {
            this.notify('success', '操作成功', '停用限流配置操作成功');

            // 刷新列表
            this.getPageLimitConfigList();
          })
          .catch(() => {})
          .finally(() => {
            // 按钮恢复可用
            this.buttonLoad = false;
          })
      },
      /**
       * 批量删除限流配置数据事件
       */
      batchDeleteLimitConfigHandle() {
        // 按钮禁用
        this.buttonLoad = true;
        this.$confirm('您确定要批量删除限流配置操作吗？删除操作不可逆，是否继续？', '删除提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            let limitConfigList = this.limitConfigSelection;
            // 获取限流配置数据主键
            limitConfigList = limitConfigList.map(limitConfig => {
              return {
                id: limitConfig.id,
                requestKey: limitConfig.requestKey,
                type: limitConfig.type,
                status: limitConfig.status
              }
            });
            return this.$axios.$delete('/sys/limit-config/batch/delete', { data: limitConfigList })
          })
          .then(() => {
            this.notify('success', '操作成功', '批量删除限流配置操作成功');

            // 刷新列表
            this.getPageLimitConfigList();
          })
          .catch(() => {})
          .finally(() => {
            // 按钮恢复可用
            this.buttonLoad = false;
          })
      },
    }
  }
</script>

<style scoped>
  .limit-page .l-tool {
    margin-bottom: 7px;
  }
  .limit-page .paging {
    float: right;
    margin: 7px;
  }
</style>
